package com.plat.project.common;


import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.plat.api.config.QiNiuConfig;
import com.plat.api.util.PropertiesUtil;
import com.plat.api.util.QiNiuUtil;
import com.plat.common.utils.file.FileUploadUtils;
import com.plat.common.utils.video.FFmpegUtil;
import com.plat.framework.web.controller.BaseController;
import com.plat.framework.web.domain.AjaxResult;
import com.plat.project.app.SystemParam;
import com.plat.project.system.domain.SysConfig;
import com.qiniu.util.Auth;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import static com.plat.api.util.QiNiuUtil.getAuth;

/**
 * Created with IntelliJ IDEA.
 * User: shish
 * Date: 2020/5/25
 * Time: 21:35
 * Description: No Description
 */
@RequestMapping("/sys/file")
@RestController
public class UploadController extends BaseController {
    private static Map<String, String> imageContentType = new HashMap<>();


    static {
        imageContentType.put("jpg", "image/jpeg");
        imageContentType.put("jpeg", "image/jpeg");
        imageContentType.put("png", "image/png");
        imageContentType.put("tif", "image/tiff");
        imageContentType.put("tiff", "image/tiff");
        imageContentType.put("ico", "image/x-icon");
        imageContentType.put("bmp", "image/bmp");
        imageContentType.put("gif", "image/gif");
    }

    @Autowired
    private SystemParam systemParam;

    /**
     * 上传
     */
    // @PreAuthorize("@ss.hasPermi('system:content:upload')")
    @PostMapping("/upload")
    public JSONObject upload(HttpServletRequest request) throws Exception {
        String uploadPath = systemParam.getParam("sys:upload:url");
        String uploadM3u8Path = systemParam.getParam("sys:upload:m3u8:url");
        String url = systemParam.getParam("sys:admin:video:url");
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        String normalPath = "";
        String m3u8Path = "";
        String qiniuUrl = "";
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // normalPath = FileUploadUtils.upload(uploadPath, entity.getValue());//
//            String type = FileTypeUtil.getTypeByPath(uploadPath + normalPath);
//            if (type.toLowerCase().equals("mp4") || type.toLowerCase().equals("mkv")) {
//                m3u8Path = FFmpegUtil.toM3U8(uploadPath + normalPath, uploadM3u8Path, RandomUtil.randomString(10) + ".m3u8");
//            }
            String key = entity.getValue().getOriginalFilename();
            QiNiuUtil.uploadMultipartFile(entity.getValue(), key, true);
            qiniuUrl = PropertiesUtil.getQiniuFileUrl() + "/" + key;
        }
        //转码m3u8,返回m3u8地址
        logger.info("上传地址,七牛云地址={}", qiniuUrl);
        JSONObject json = new JSONObject();
        //json.put("url", videoUrl);
        json.put("url", qiniuUrl);//使用七牛云地址
//        json.put("m3u8Url", url + m3u8Path);
//        json.put("qiniuUrl", qiniuUrl);
        return json;
    }

    /**
     * 七牛云上传和获取token
     *
     * @param key 文件名称（例如 wenjian.txt）
     */
    @PostMapping("/upload/getToken")
    public AjaxResult getToken(String key) throws IOException {
        Auth auth = getAuth();
        String upToken = auth.uploadToken(QiNiuConfig.getInstance().getBucket(), key);//覆盖上传凭证
        JSONObject json = new JSONObject();
        json.put("token", upToken);
        json.put("uploadUrl", PropertiesUtil.getQiniuFileUrl());
        return AjaxResult.success(json);
    }

    /**
     * 预览图片
     */
    @GetMapping("/view/photo/{url}")
    public void viewPhoto(@PathVariable String url, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String uploadPath = systemParam.getParam("sys:upload:url");

        File image = new File(uploadPath + url);
        FileInputStream inputStream = new FileInputStream(image);
        int length = inputStream.available();
        byte data[] = new byte[length];
        response.setContentLength(length);
        String fileName = image.getName();
        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        response.setContentType(imageContentType.get(fileType));
        inputStream.read(data);
        OutputStream toClient = response.getOutputStream();
        toClient.write(data);
        toClient.flush();
        IOUtils.closeQuietly(toClient);
        IOUtils.closeQuietly(inputStream);
    }

    /**
     * 预览视频
     */
//    @PreAuthorize("@ss.hasPermi('system:file:view')")
    @GetMapping("/view/{year}/{month}/{day}/{filename}")
    public void view(@PathVariable String year,
                     @PathVariable String month,
                     @PathVariable String day,
                     @PathVariable String filename,
                     HttpServletRequest request, HttpServletResponse response) throws IOException {
        String uploadPath;
        if (filename.contains("m3u8")) {
            uploadPath = systemParam.getParam("sys:upload:m3u8:url");
        } else {
            uploadPath = systemParam.getParam("sys:upload:url");
        }
        response.reset();
        //获取从那个字节开始读取文件
        String rangeString = request.getHeader("Range");
        try {
            //获取响应的输出流
            OutputStream outputStream = response.getOutputStream();
            File file = new File(uploadPath + "/" + year + "/" + month + "/" + day + "/" + filename);
            if (file.exists()) {
                RandomAccessFile targetFile = new RandomAccessFile(file, "r");
                long fileLength = targetFile.length();
                //播放
                if (rangeString != null) {
                    long range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));
                    //设置内容类型
                    response.setHeader("Content-Type", "video/mp4");
                    //设置此次相应返回的数据长度
                    response.setHeader("Content-Length", String.valueOf(fileLength - range));
                    //设置此次相应返回的数据范围
                    response.setHeader("Content-Range", "bytes " + range + "-" + (fileLength - 1) + "/" + fileLength);
                    //返回码需要为206，而不是200
                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                    //设定文件读取开始位置（以字节为单位）
                    targetFile.seek(range);
                } else {//下载
                    //设置响应头，把文件名字设置好
                    response.setHeader("Content-Disposition", "attachment; filename=");
                    //设置文件长度
                    response.setHeader("Content-Length", String.valueOf(fileLength));
                    //解决编码问题
                    response.setHeader("Content-Type", "application/octet-stream");
                }

                byte[] cache = new byte[1024 * 300];
                int flag;
                while ((flag = targetFile.read(cache)) != -1) {
                    outputStream.write(cache, 0, flag);
                }
            } else {
                String message = "file:" + " not exists";
                //解决编码问题
                response.setHeader("Content-Type", "application/json");
                outputStream.write(message.getBytes(StandardCharsets.UTF_8));
            }
            outputStream.flush();
            outputStream.close();
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }
    }
}
